package com.authine.cloudpivot.ext.controller.dingtalk;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.authine.cloudpivot.engine.api.exceptions.ServiceException;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectQueryModel;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.component.query.api.FilterExpression;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.component.query.api.helper.PageableImpl;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.type.OrgSyncType;
import com.authine.cloudpivot.engine.enums.type.QueryDisplayType;
import com.authine.cloudpivot.ext.model.BaseModel;
import com.authine.cloudpivot.web.api.controller.DingtalkController;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.dubbo.DubboConfigService;
import com.authine.cloudpivot.web.api.exception.ResultEnum;
import com.authine.cloudpivot.web.api.lock.LockService;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;
@Api(
        value = "钉钉同步接口",
        tags = {"钉钉::钉钉同步接口::新"}
)
@Controller
@RequestMapping({"/api/dingding"})
public class DingDingController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(DingtalkController.class);
    @Autowired
    private DubboConfigService dubboConfigService;
    @Autowired
    private LockService lockService;
    @ApiOperation(
            value = "钉钉一键立即同步接口",
            notes = "钉钉一键立即同步"
    )
    @GetMapping({"/synchorize/organization"})
    @ResponseBody
    @ApiImplicitParams({@ApiImplicitParam(
            name = "isSyncRoleScope",
            value = "是否同步角色管理范围：0-否，1-是"
    ), @ApiImplicitParam(
            name = "isSyncDeptSetting",
            value = "是否同步部门管理范围：0-否，1-是"
    )})
    public ResponseResult<?> dingtalkSynchronize(Integer isSyncRoleScope, Integer isSyncDeptSetting) {

        List<String> columns = Lists.newArrayList();
        columns.add("deptId");
        columns.add("appkey");
        columns.add("appSecret");
        columns.add("id");
        FilterExpression filter =
                new FilterExpression.Item(BaseModel.sequenceStatus, FilterExpression.Op.Eq, "COMPLETED");
        BizObjectQueryModel query = new BizObjectQueryModel();
        query.setSchemaCode("shangxi_town_code");
        query.setQueryCode("shangxi_town_code");
        query.setFilterExpr(filter);
        BizObjectQueryModel.Options options = new BizObjectQueryModel.Options();
        options.setQueryDisplayType(QueryDisplayType.OVERRIDE);
        options.setCustomDisplayColumns(columns);
        query.setOptions(options);
        query.setPageable(new PageableImpl(0, Integer.MAX_VALUE));
        Page<BizObjectModel> resultPage = dubboConfigService.getBizObjectFacade().queryBizObjects(query);
        List<BizObjectModel> content = Lists.newArrayList();
        if (resultPage != null) {
            content = (List<BizObjectModel>) resultPage.getContent();
            for (BizObjectModel bizObjectModel : content) {
                if (bizObjectModel.getData().get("id") == null) {
                    continue;
                }
                String relatedId = String.valueOf(bizObjectModel.getData().get("id"));
                if (StringUtils.isNotBlank(relatedId)) {
                    RelatedCorpSettingModel relatedCorpSettingModel = this.getSystemManagementFacade().getRelatedCorpSettingModel(relatedId);
                    if (null == relatedCorpSettingModel) {
                        return ResponseResult.builder().errcode(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrCode()).errmsg(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrMsg()).build();
                    }
                    this.organizationDTSync(this.getUserId(), relatedId, isSyncRoleScope, isSyncDeptSetting);
                } else {
                    List<RelatedCorpSettingModel> relatedCorpSettingModels = this.getSystemManagementFacade().getAllRelatedCorpSettingModel();
                    if (CollectionUtils.isEmpty(relatedCorpSettingModels)) {
                        return ResponseResult.builder().errcode(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrCode()).errmsg(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrMsg()).build();
                    }

                    relatedCorpSettingModels = (List)relatedCorpSettingModels.stream().filter(Objects::nonNull).filter((item) -> {
                        return OrgSyncType.PULL == item.getSyncType();
                    }).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(relatedCorpSettingModels)) {
                        return ResponseResult.builder().errcode(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrCode()).errmsg(ResultEnum.DINGTALK_CONFIG_EMPTY_ERR.getErrMsg()).build();
                    }

                    relatedId = ((RelatedCorpSettingModel)relatedCorpSettingModels.get(0)).getId();
                    this.organizationDTSync(this.getUserId(), relatedId, isSyncRoleScope, isSyncDeptSetting);
                }

                if (isSyncRoleScope == null) {
                    isSyncRoleScope = 0;
                }
            }
        }
        return ResponseResult.builder().errcode(ResultEnum.SUCCESS.getErrCode()).errmsg(ResultEnum.SUCCESS.getErrMsg()).build();

    }

    private ResponseResult<Object> organizationDTSync(String userId, String relatedId, Integer isSyncRoleScope, Integer isSyncDeptSetting) {
        Lock lock = this.lockService.getDingtalkSyncLock();
        boolean locked = false;

        ResponseResult var9;
        try {
            locked = lock.tryLock(3L, TimeUnit.SECONDS);
            if (!locked) {
                throw new ServiceException(ErrCode.SYS_DINGTALK_SYNC_DOING_ERROR);
            }

            Object object = this.getOrganizationFacade().syncOrganization(userId, relatedId, isSyncRoleScope, isSyncDeptSetting);
            if (!(object instanceof Map)) {
                return ResponseResult.builder().errcode(ResultEnum.DING_SYNC_ERR.getErrCode()).errmsg(ResultEnum.DING_SYNC_ERR.getErrMsg()).build();
            }

            Map<String, String> map = (Map)object;
            if (map.isEmpty()) {
                var9 = ResponseResult.builder().errcode(ResultEnum.SUCCESS.getErrCode()).errmsg(ResultEnum.SUCCESS.getErrMsg()).build();
                return var9;
            }

            if (map.get("error") != null) {
                var9 = ResponseResult.builder().errcode(ResultEnum.DING_SYNC_ERR.getErrCode()).data(map).errmsg(ResultEnum.DING_SYNC_ERR.getErrMsg()).build();
                return var9;
            }

            var9 = this.getOkResponseResult(map, "异常用户");
        } catch (InterruptedException var13) {
            log.error(var13.getMessage(), var13);
            return ResponseResult.builder().errcode(ResultEnum.DING_SYNC_ERR.getErrCode()).errmsg(ResultEnum.DING_SYNC_ERR.getErrMsg()).build();
        } finally {
            if (locked) {
                lock.unlock();
            }

        }

        return var9;
    }

}
